{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "#coding=gbk\n",
    "\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import tensorflow as tf\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from modelBATTERY\\model.ckpt-1000\n",
      "Load!\n"
     ]
    },
    {
     "ename": "ValueError",
     "evalue": "x and y must have same first dimension, but have shapes (98,) and (19,)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-2-10e672579aa5>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m    153\u001b[0m \u001b[1;31m# train_lstm()\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    154\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 155\u001b[1;33m \u001b[0mprediction\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32m<ipython-input-2-10e672579aa5>\u001b[0m in \u001b[0;36mprediction\u001b[1;34m(time_step)\u001b[0m\n\u001b[0;32m    145\u001b[0m \u001b[1;31m#         prediction=plt.plot(list(range(len(test_predict1))), test_predict1, color='b',label='predict')\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    146\u001b[0m         \u001b[0mprediction\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;36m300\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtest_predict1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'b'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlabel\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'predict'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 147\u001b[1;33m         \u001b[0mprediction\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m301\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtest_predict2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'g'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlabel\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'predict1'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    148\u001b[0m         \u001b[0mtest\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlist\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtest_y\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtest_y\u001b[0m\u001b[1;33m,\u001b[0m  \u001b[0mcolor\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'r'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlabel\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'real_soh'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    149\u001b[0m         \u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mshow\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32md:\\anaconda3\\envs\\tensorflow\\lib\\site-packages\\matplotlib\\pyplot.py\u001b[0m in \u001b[0;36mplot\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m   3356\u001b[0m                       mplDeprecation)\n\u001b[0;32m   3357\u001b[0m     \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 3358\u001b[1;33m         \u001b[0mret\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0max\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m   3359\u001b[0m     \u001b[1;32mfinally\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   3360\u001b[0m         \u001b[0max\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_hold\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mwashold\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32md:\\anaconda3\\envs\\tensorflow\\lib\\site-packages\\matplotlib\\__init__.py\u001b[0m in \u001b[0;36minner\u001b[1;34m(ax, *args, **kwargs)\u001b[0m\n\u001b[0;32m   1853\u001b[0m                         \u001b[1;34m\"the Matplotlib list!)\"\u001b[0m \u001b[1;33m%\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mlabel_namer\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfunc\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__name__\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   1854\u001b[0m                         RuntimeWarning, stacklevel=2)\n\u001b[1;32m-> 1855\u001b[1;33m             \u001b[1;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0max\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m   1856\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   1857\u001b[0m         inner.__doc__ = _add_data_doc(inner.__doc__,\n",
      "\u001b[1;32md:\\anaconda3\\envs\\tensorflow\\lib\\site-packages\\matplotlib\\axes\\_axes.py\u001b[0m in \u001b[0;36mplot\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m   1525\u001b[0m         \u001b[0mkwargs\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcbook\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mnormalize_kwargs\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0m_alias_map\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   1526\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1527\u001b[1;33m         \u001b[1;32mfor\u001b[0m \u001b[0mline\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_get_lines\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m   1528\u001b[0m             \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0madd_line\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mline\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   1529\u001b[0m             \u001b[0mlines\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mline\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32md:\\anaconda3\\envs\\tensorflow\\lib\\site-packages\\matplotlib\\axes\\_base.py\u001b[0m in \u001b[0;36m_grab_next_args\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m    404\u001b[0m                 \u001b[0mthis\u001b[0m \u001b[1;33m+=\u001b[0m \u001b[0margs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    405\u001b[0m                 \u001b[0margs\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0margs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 406\u001b[1;33m             \u001b[1;32mfor\u001b[0m \u001b[0mseg\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_plot_args\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mthis\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    407\u001b[0m                 \u001b[1;32myield\u001b[0m \u001b[0mseg\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    408\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32md:\\anaconda3\\envs\\tensorflow\\lib\\site-packages\\matplotlib\\axes\\_base.py\u001b[0m in \u001b[0;36m_plot_args\u001b[1;34m(self, tup, kwargs)\u001b[0m\n\u001b[0;32m    381\u001b[0m             \u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mindex_of\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtup\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    382\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 383\u001b[1;33m         \u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_xy_from_xy\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    384\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    385\u001b[0m         \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcommand\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m'plot'\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32md:\\anaconda3\\envs\\tensorflow\\lib\\site-packages\\matplotlib\\axes\\_base.py\u001b[0m in \u001b[0;36m_xy_from_xy\u001b[1;34m(self, x, y)\u001b[0m\n\u001b[0;32m    240\u001b[0m         \u001b[1;32mif\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m!=\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    241\u001b[0m             raise ValueError(\"x and y must have same first dimension, but \"\n\u001b[1;32m--> 242\u001b[1;33m                              \"have shapes {} and {}\".format(x.shape, y.shape))\n\u001b[0m\u001b[0;32m    243\u001b[0m         \u001b[1;32mif\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mndim\u001b[0m \u001b[1;33m>\u001b[0m \u001b[1;36m2\u001b[0m \u001b[1;32mor\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mndim\u001b[0m \u001b[1;33m>\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    244\u001b[0m             raise ValueError(\"x and y can be no greater than 2-D, but have \"\n",
      "\u001b[1;31mValueError\u001b[0m: x and y must have same first dimension, but have shapes (98,) and (19,)"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAD8CAYAAACb4nSYAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzt3Xl8VNXZwPHfQ4Qgu2GXsGpUFpElohTBBVG0rYgrWGutbdFWfW3VKlTfqrRqLdj2VUGllmoXRXBFiyuIWleCgLIYDAgSNtk3QQie94/nXu/NZCaZJJNkluf7+cznzt1mznXwuSfnnvMccc5hjDEmM9Sr6wIYY4ypPRb0jTEmg1jQN8aYDGJB3xhjMogFfWOMySAW9I0xJoNY0DfGmAxiQd8YYzKIBX1jjMkgh9R1ASK1atXKdenSpa6LYYwxKWX+/PmbnXOtKzou6YJ+ly5dKCgoqOtiGGNMShGR1fEcF1fzjogMF5FCESkSkbFR9ncWkdki8rGIzBWR3NC+gyKy0HvNjP8SjDHGJFqFNX0RyQImAcOAYmCeiMx0zi0NHTYR+Idz7jEROQ24G/iht2+vc65PgsttjDGmCuKp6Q8AipxzK51z+4FpwIiIY3oAs733b0TZb4wxJgnEE/Q7AGtC68XetrBFwPne+5FAUxFp6a03FJECEXlfRM6tVmmNMcZUSzxBX6Jsi0zCfyNwsogsAE4G1gIl3r5Ozrl84BLgLyJyRJkvEBnj3RgKNm3aFH/pjTHGVEo8Qb8Y6BhazwXWhQ9wzq1zzp3nnOsL3OJt2+Hv85YrgblA38gvcM5Ncc7lO+fyW7eusMeRMcaYKoon6M8D8kSkq4g0AEYBpXrhiEgrEfE/axww1dt+mIhk+8cAg4DwA2BjjDG1qMKg75wrAa4BXgGWAdOdc0tEZLyInOMddgpQKCLLgbbAnd727kCBiCxCH/D+IaLXj6mGp5+G9evruhTGmFQiyTZHbn5+vrPBWRVbvx4OPxyGDoXXX6/r0hhj6pqIzPeen5bLcu+kqHnzdLltW92WwxiTWjI66L/wAixYUPvf6xx8/nnZ7QcOwIQJsHdvxZ/h/zHUsWP5xxljTFjaBX3n4J57YMWKio8dMwbuuqvmyxRp1iw44ghYubL09nfegZtugldfrfgz/Jr+V18lvnzGmPSVdkF/0yYYOxYefTT2MdOmadDcuBHWrq35Mu3dqwHdt2iR3pyKikof9+WXutywQcsWi3NB0N+8ObFlNcakt7QL+hs26HJ1Ofnmfv5zuP56DZ7r1sU+LlFuuQVOOgk++UTX/WAf2fPGD/rvvqsPad94A1at0nKGbd4MW7boe39pjDHxSNugv2pV9P379sH27fDhh7q+bh18803Nlslvxpk/X5d+0I+84fiDkd98U8v0yivaDDRzJowfH9wkiot12a2b1fSNMZWTUUH/wIFg//79wbaaDpwtWujygw90Ga2mv39/EPT9v1LefluD//PPw223wfTput1vkjruOG3Tt3Z9Y0y80jbor10bBHbfscfCDTeUPeeHP4SHHw7W//1veOKJxJXJb59/913YsycI9n5N/5NPoEkTmDu39Hl+zyL/r5I1Xto7v6Z/3HG63LJF/4I5eDBxZTbGpKe0DfrffBMER9BgW1gIL71U9pxXX4V//StYnzAB/vSnYH3XLti6tepl8oP84sWwcGHZ7QsX6l8cy5aVPs/vurnUG8PsB/21ayErC3r21PUtW+CYY+D++6teRmNMZki7oB/u9eI38ezeHbwP94Fv2DB4v3y51pSd06Aabm+/8kr43veqXqb166F1a70R/ec/uu2YY7Tmf8QRuiyP/yB3zRr4+mu9mbVrB23b6va1a7VJqLCw6mU0xmSGtAn6Bw/qg88FC6B9e902dKj2ic/Lg1/9quw5vXsH77/8EgYPhssu0zb+DRugxEsO/dFH+hDWX6+MkhJtqx88WNf9oH/KKbpcuRJmzIjvsz79FNq00e6oHTpAy5bBZ4CNzjXGVCxtgv4XX8Dw4dpEkp8fNH3cfLMG8HB+mmbNoGlT6Ny59Ge8954+NAWtlb/1lt5EVqzQ5wOR/erjsXGj1tRPOknXP/4YcnO1540v3O2yXTtdSpRZDLZtg5079X1uLrRqpe/9gWjVaYIyxmSGtAn6XbtqzR60Frx4MZx3ni6hdF/3tm3hvvu09j9xonaH9O3aFbwfORJOPTWo4S9Zosv9+7XJKJatW4NRtX67fbduWi6A7t3hkBizE/fqFRwD0YM/QL16kJOj7/2bkdX0jTEVSZugD9o0A8HD3O98J/pxbdvC5ZfDwIHam+emmzSIRtq5E3bsCNb9oP/rX8OgQdqffsIEbVN//XVtSjr/fHjgAf2rY+vWIOi3bw9HHqnvjzlGnxM8+CCcdppua95clwMG6HLIEF326KHLTp106TfptGypN44WLYKavgV9Y0xF0iroX3QRXHABjBun6wMH6tKvVefl6dJ/AOrLzoYuXXQZS8uWwV8Nr72m3SzvvRd+8xu480590Pvcc/DMM9pM5Jw+WPUTq4WDfvfu0KgRXHVVULP//vd1OXKkpljwb2D+TcC/llGjYM4c+OMfdb1Vq+A7tm7VMlozjzEmlrQK+g0b6kNRP1D266c14VGjdL1XL60x+8E3bMoUePxxfZ+drV0ifTk5cPrp8NRTcMkl+tzAOZg9W5t+Xn9de9X4g6/eekuXS5fCQw/p+IDc3NI1fZ//fuRI7ZWTn6+v/v3huuv0Vb8+nHuubrvoIm1yatZMz2vVSr8bdKTxkCF6EzLGmGhitCynh4YNtStm48Z6M+jSBSZPDgJm2NCh+vC2YUPNe/P119o0c+GF2s3zgQf0ZvCPfwTn+CNhP/tMl35uHX/7hAla23/8cW2bHzpUewz16xd8xpAh2p2zX7+gzR+gQQP4y1/0/erV+oDXv3mF+c09oDeibduCmv+77+pfGF27xv2fzBiT5jJm5qy339bmHb93TCzHHqs1+717tU1/2bLgYerWrZq/fu/esknQYmnfXnsWxXpwW12XXw6PPVZ624knasBv00ZvNNOm1cx3G2OSR7wzZ6V1TT/M7ydfkcmTtZa9caP2/Q/3nsnJgRtv1NTI779ffvpj36hRNRfwIei2GbZ+vY412LxZ2/hfeUWfY/TpU3PlMMakhowJ+vGq6OZwxx3BcRs3ajCNFvybN9eeP6NHJ76MYeHmHd/69UHqhuXL9cYzcKD2LjLGZLa0epBbm447Th/O5nt/TB1xhC79Ub6zZmmXzPwK/9iqHr+mH37wvH+/9iACzemzfbuO5jXGmLiCvogMF5FCESkSkbFR9ncWkdki8rGIzBWR3NC+H4nIZ97rR4ksfF266y6dDatfP23n799ft19+uQb+E07QLpmxBlclih/0/X78vjlzSq+vWhXf3LtVtX9/xTmEjDF1r8KgLyJZwCTgLKAHMFpEekQcNhH4h3OuNzAeuNs7Nwe4DTgBGADcJiKHJa74dadZMw20t96qbfy9e2tTy3XX6Xq45l2T/OadLl2CcoHOunXMMcFNxzlt6qkpU6dqqolwZlNjTPKJp6Y/AChyzq10zu0HpgEjIo7pAcz23r8R2n8m8JpzbqtzbhvwGjC8+sVOHg0awGGH6QPeTz6JPrK3Jvk1/XbtdMCXP4irpET/CunbV0cPQ8028SxYoDeWeCakN8bUnXge5HYA1oTWi9Gae9gi4Hzg/4CRQFMRaRnj3A6koezsILtnbfKDfvPm8Oyz2tTkp264+GIdVFZSovsvu0xvDP7o30TyHxyXNzexMabuxVMvjdYqHdlL/UbgZBFZAJwMrAVK4jwXERkjIgUiUrDJnzPQxCUnR5uScnLgjDOCRG2gwb1RI23yad9e292vuCLx0ys6F+QlsqBvTHKLJ+gXAx1D67lAqSm9nXPrnHPnOef6Ard423bEc6537BTnXL5zLr9169aVvITMdsghmvPnF78Its2YoSmcww+RX35ZU01s3qzLRNqwIUj2ZkHfmOQWT/POPCBPRLqiNfhRwCXhA0SkFbDVOfcNMA6Y6u16Bbgr9PD2DG+/SaDIWb0uuKDsMb176+vJJ/X5Q05OkNStuvymnUMOiT4hvTEmeVRY03fOlQDXoAF8GTDdObdERMaLyDneYacAhSKyHGgL3OmduxX4HXrjmAeM97aZOvLMMzqw7Kqrghw9GzbErqEfOFA6vXQ0fq+ggQOtpm9Msourr4lzbpZz7ijn3BHOOT+g/9Y5N9N7/5RzLs875qfOua9D5051zh3pvf5eM5dh4tWsmSaNy8oKUlBffLHeCPbvL3v8dddpDp+LLw7SOUfyUzn366d5hr75pmbKboypPhuRm4E6dtT0EC+/rP3q335bJ13/179KH7dxo/a/79RJZwK7+eboA7x27NDspMccozeO0aNrdiCYMabqLOhnqJNP1mB9xx3a+6ZjR/j972HfvuCYP/xBU0y/+KImooPo/fC3b9cuoaNG6QPl6dP12UHY6tU6b7E1/xhTtyzoZyh/OsZHHtF+/X//u7bx+00406drPv8rr4Sjj4ajjtLt/twBYTt2aNBv0ULnHTj6aHj44dLHzJunD3z/+9+auyZjTMUs6GeojqGOtH/+s+bdHzYsmD3s6ac1odz99+u6P9VktFQOftAH7SY6Zoymnl65MjjGnys42k3DGFN7LLVyBnvsMdi1Swd1gebv8Wf/2rhRZ9yqX1/XmzXTNNKxavotWgTr/nSVy5frnAR5ebDOG51hQd+YumVBP4NF9tNv1kxnCwPtxnnssaX35+XFDvq5ucF6t266nDwZXnhBZx+zmr4xycGad8y3mjXTFA0lJVrTj5xaMi+v4uYd0POys+Gll3R95cog6C9fHv9Uk8aYxLOgb77lp2XevFl75LRtW3r/ccfpXwDTpsE11wTB2++946tXT5uKSkp0fcOGIOjv2KGfb4ypGxb0zbf8oF9UpMvIoD90qC6vuAImTdIa/IED+tdBOOhD0MQDQdD3Hx7ffbe29Rtjap8FffMtP+j77e6RzTs9e+qNwB949eGHwTOA8INc0IfAvi++0Nr9D38IF16ovYWefz7x5TfGVMyCvvmWH/T9dvvImr6I5ucHbcL54IMgL09kTT8c9Bct0mXnzvDPf2qPoA8/TGzZjTHxsd475ltNm+oyVk0f4Prr9YHu66/DW2/BOV7Kvcig36+fZt3s0EFn1QLN6Z+drdk+Cwpq5hqMMeWzmr75VmTzTps2ZY/p1w9uu00nfl+wIGjnjwz6p50GX34JJ56oqRwgaOfPz9egb714jKl9FvTNt8LNO82baxK1WK69Vmv9vsg2fdC5g/2/FnJyglm98vO1Wcjm0zWm9lnQN9/yg/6+fXD44eUf27kzTJwYrEfW9H1+0O/fP5g03p+8/emnNbPnnj1VL7MxpnIs6JtvNWkSvA8/iI1FBM46S9+3bBn9GD+3/tFHB9t69tQsn+PGaY+ee++tWnmNMZVnQd98KysLGjfW9/EEfYBnn9WeOLFq+n6t/pJLSm8fO1bb9Bs2hL/9zfrtG1NbLOibUvzgG2/Qz86G44+Pvf/UU7Vfvx/8fcOHa3K3v/9d+/HPmVO18hpjKseCvinFn0QlPKK2umI9EO7VS7t8ZmXB3Lm6zXr0GFOzLOibqOKt6VdXo0aa0+eDD2DTJmjVSpuMjDE1w4K+iaq2gj5oX/4PP4RnntFJ1l98sfa+25hMY0HfRBXrwWxNOOEEnczl7rt1/Z13au+7jck0cQV9ERkuIoUiUiQiY6Ps7yQib4jIAhH5WETO9rZ3EZG9IrLQez2U6AswifXkk/C739Xud550krbrr16tN5vCQku/bExNqTD3johkAZOAYUAxME9EZjrnloYOuxWY7px7UER6ALOALt6+Fc65PokttqkpF11U+9/ZrRu8/bY26/TuDaNGwc03a4qH7t21zf/997Wvf6zxAMaY+MSTcG0AUOScWwkgItOAEUA46DvAG89Jc2BdIgtp0t/Agfrat0/n2H30UZg6VfeNGwcTJuiE65Mm1WkxjUl58TTvdADWhNaLvW1htwOXikgxWsu/NrSvq9fs86aIDI72BSIyRkQKRKRg06ZN8ZfepJ2GDbUnz1dfweLFWsufOFFn4Zo1y7p0GlNd8QR9ibIt8n+90cCjzrlc4GzgnyJSD1gPdHLO9QWuBx4XkWYR5+Kcm+Kcy3fO5bdu3bpyV2DSUna2pmu48EKdnQtg1Spt7zfGVF08Qb8Y6Bhaz6Vs881PgOkAzrn3gIZAK+fc1865Ld72+cAK4KjqFtpkDj9fvz+id+xYWBel8XDRIr0pGGPKF0+b/jwgT0S6AmuBUUBEJhW+AIYCj4pIdzTobxKR1sBW59xBEekG5AErE1Z6k/Z69dKHuuedp/34//hHncRl1Spt+rn1Vj3unHP0L4NZs+q0uMYkPXFxNJJ6XTD/AmQBU51zd4rIeKDAOTfT67HzV6AJ2vRzk3PuVRE5HxgPlAAHgduccy+U9135+fmuwKZVMjG0awfnngsPP6zrGzZoO3/79jrz17Zt2v3TmEwjIvOdc/kVHRfXdInOuVnoA9rwtt+G3i8FBkU572ng6Xi+w5h4HHqoPuT1/fnPMNjrHrBrF3z8MfTtWzdlMyYV2Ihck1IaNYKdO4P1t96C+fOD9f/+t/bLZEwqsaBvUkqjRrBlS7C+cKEO3OreHTp1shQOxlTEgr5JKYceGqRoGDRIc/W/9prm7+nfX28CxpjYLOiblNKoURD0/bb8khK44gpN4fDZZ6Xb/I0xpVnQNymlUSNNvwzQp4/22OndW5O29e6tc/IuXVr+ZxiTyeLqvWNMsjj00GCy9SZN4LHHtC1fRIM+wPPPQ4cO2o3TGFOaBX2TUho1Kv3+u98N1v0pHn//e5g9G959t3bLZkwqsOYdk1Iig35YvXowerS+f+892L+/9splTKqwoG9SyqGHRn/ve/xxeNobDvjRR7VTJmNSiQV9k1LKq+n7Bnljw2+9VROxGWMCFvRNSokn6Ldtqw9xZ8+um5nAjElmFvRNSgk36cQK+gAzZkCPHrB8ORQX25y7xvgs6JuUEk9NH7SJ59579X3fvtqzZ8aMmi2bManAgr5JKX6gz8qC+vXLP3bAAF1u3qzTMI4eDa+/XrPlMybZWdA3KcVv3mnUSAdklScnB44+WgdxffSRJmW78EJt8nn2Wbj//povrzHJxgZnmZTi1/SjddeM5u67NSlbbi688ILW/vv3h927dX/37nD66TVTVmOSkQV9k1L8oF9ee37YyJHB+y5d4I03tK2/fn2YMweuvhoWL664qciYdGHNOyalhJt3qqJnT5g6Vadb/NOftKnnb39LXPmMSXYW9E1KqWxNvzzf+x585ztBLx9jMoEFfZNSEhn0RbSN/8svq/9ZxqQKC/ompVS3eSfa5331FezbBxs3xn/enj3aTHTwYGLKYUxtiSvoi8hwESkUkSIRGRtlfycReUNEFojIxyJydmjfOO+8QhE5M5GFN5knkTV90KBfUgJXXgnt2sGuXeBcxcH88cfhJz+BF19MTDmMqS0VBn0RyQImAWcBPYDRItIj4rBbgenOub7AKGCyd24Pb70nMByY7H2eMVXSsKEu4+2yWRH/5vHWW7p88km47z7o2FFr/7EsWKDLqVMTUw5jaks8Nf0BQJFzbqVzbj8wDRgRcYwDmnnvmwPrvPcjgGnOua+dc58DRd7nGVMl9epp4E9kTR8gL0+XDz0EkyfD+vXw5ptlj9++XXv7+EH/P/+xZwImtcQT9DsAa0Lrxd62sNuBS0WkGJgFXFuJc42plL59oVevxHyWf/PYtEmX8+drN06I3nRz553w05/C++/rHL0HD0JBQWLKErZpkw4qMybR4gn60Qa7u4j10cCjzrlc4GzgnyJSL85zEZExIlIgIgWb/P/7jInh3Xfhf/4nMZ/l1/Q3b9aePOeeC82bw5AhOhnLSy+VPj78z/MHP9DlggXaLOTP3ZsIAwfCXXcl7vOM8cUzIrcY6BhazyVovvH9BG2zxzn3nog0BFrFeS7OuSnAFID8/PwyNwVjaopf09+8WZt4nnoKtmzRUbrnn69z8G7YAG3a6HH+XwEAp5yi6R1uvVXXmzaFs88mIdatgy++SMxnGRMWT01/HpAnIl1FpAH6YHZmxDFfAEMBRKQ70BDY5B03SkSyRaQrkAd8mKjCG1Ndfk1/3z5o3Fizd7ZpA6edBjNnak+e99/XY5zTm8Gll8KUKZrDJ9zMtGNHYsrknJZn167EfJ4xYRUGfedcCXAN8AqwDO2ls0RExovIOd5hNwA/E5FFwBPA5U4tAaYDS4GXgaudc9az2SSN8APhxo1L78vPh0MO0UnWAdas0UA8aBD87Gc6uCsc9NevT0yZDhzQwL9zZ2I+z5iwuBKuOedmoQ9ow9t+G3q/FBgU49w7gTurUUZjakx5M3Edeqg+NL7nHvj8c+25A6UDffj92rWJKZPfVdRq+qYm2Ihck9HKq+mD1vad08lXli3ThG19+gT7zz8fJkyATp20HT4R/KBvNX1TEyy1ssloFc25+8tf6riA//1fOOywsvubNIEbb9Rc/VbTN6nAavomo1VU0z/qKE3BHC3gh3XoUDM1/VdfhU8/TcznGgNW0zcZrqKafrwOP1yDvnMVT+NYET/o794NZ3rZqvbsSdwoZJPZrKZvMlo46Eer6cfr8MN1BO2wYbBqVfXK5Ad9FxqxMnFi9T7TGJ8FfZPR6tWD7Gx9X52adPv2upw9G264oXplipbobe7c6n2mMT4L+ibj+bX96tT0TzxRu3defDE88wwsWlT1z4oM+s2bw5IlVf88Y8Is6JuMl4gc/V27wkcfaU8egNWrq/5ZkUH/1FM1k+fmzVX/TGN8FvRNxktETd/XpIku9+yp+mdEBv3TTtPl0qVV/0xjfBb0Tcbza/iJCPr+Z+zeXfXPiBX0rYnHJIIFfZPxEjnvrl/T370bnnhCa/zXXqv9/SdO1AyeU6aUn0EzHPSzs6FHD83gaUHfJIL10zcZryZq+i+/rAOrunbVvD09esCvf60v0Iezc+ZAv35lPyMc9Nu00X7/Rx0FK1ZUv3zGWE3fZLxE1vQbNNDMnFu36vrnn2ttfd48TdV8++263LdPJ1ePJhz027bVZZcu+lnGVJfV9E3GS2RNH7SJJ5xmefBg/Y7vf19fAL17a2+faPygf8ghQdDv2lXn403EiF+T2Szom4zn1/QbNkzM5zVurLNt+YYNK3tM//7a5h8tiO/bpwG/ZUsd6Qta09+3D/7yFz3niiuguBjq14ejj05MuU1msKBvMl6jRvqql6DGzsaNdcJ00OB8+eVlj+nfHx56SNvpjzyy9L59+/QGNGOGpmwGDfoA11+vy8mT9dxOnao3JsBkHmvTNxnv5JPhnHMqPi5efg8e0MDuz68b1r+/LvPy4LnndCTvK6/oNj/oDx4MnTvrtq5dg3OvvFIHa4H2Atq4MXGzdpn0Z0HfZLxLLtGmlkTxnw0ceqg2v0TTq5c2+zRpAtddB9Onw9NP6z4/6If5wR/0YfDHH8NNN+n6sGF60zAmHhb0jUkwv6bfrFnsY+rX1y6dP/5x0Ge/sFCX0YJ+48bQurV2/WzXTpt7hg7VfZ98oq9wVk5jYrGgb0yC+TX98oK+z+/NA7B8udb2ly6N/lD5F78oncGze/fg/fbtOvDLmIrYg1xjEqwyQf/kkzU7Z1YWFBTABRfo9vz8ssfefnvp9dxc/avCT/mwbJlm+4zVpBTLrl0wfz6cckrlzjOpKa6avogMF5FCESkSkbFR9v9ZRBZ6r+Uisj2072Bo38xEFt6YZBRP846vQQPtr3/LLaW3x9N9VESbe5o31/UhQ2D4cJ3MZceO+Mv76KOa38cfUGbSW4U1fRHJAiYBw4BiYJ6IzHTOfZvzzzn3q9Dx1wJ9Qx+x1znXJ3FFNia5Vaam74vsax/vmIGHHoL9+7WGD/DWW9pFdOlSeOQRncWrooe8mzbp84D16yEnJ/4ym9QUT/POAKDIObcSQESmASOAWIleRwO3JaZ4xqQev6bv18Dj0a2bpmv4+mtdb9AgvvP69i29XlKiPYEguBFUFPR37tTlxo3Qs2d832tSVzzNOx2ANaH1Ym9bGSLSGegKzAltbigiBSLyvoicW+WSGpMiqlLTz86GN9+EO+/U9e3byz8+0nHHxd5XUlL+uX7Q9/v+m/QWT9CPlukjVuewUcBTzrmDoW2dnHP5wCXAX0TkiDJfIDLGuzEUbNq0KY4iGZO8qhL0AU44Ici6uW5d5c595x29UXTsqOvhwVwV/S8Vrumb9BdP0C8GOobWc4FY/yRHAaWGuTjn1nnLlcBcSrf3+8dMcc7lO+fyW7duHUeRjElelXmQG6lbN11WdoRt48banDRsGAwcCA8+GEy+UlEwt6CfWeJp058H5IlIV2AtGtgviTxIRI4GDgPeC207DPjKOfe1iLQCBgF/TETBjUlWVa3pQzDy1m/br6yHHtK8Pw0b6s1nzhx9rVgB558f/Ry/p48F/cxQYdB3zpWIyDXAK0AWMNU5t0RExgMFzjm/G+ZoYJpzpcYFdgceFpFv0L8q/hDu9WNMOqpO0M/O1u6b/mjbyqpfP+in366dLseO1W3nnRc9LbO16WeWuAZnOedmAbMitv02Yv32KOe9CxxbjfIZk3L8bo+tWlXt/N//PjHl8HPxHzigr02boid/s+adzGJpGIxJsH794IUX4PTT67YcTZqUnhjmiSfgj1EaVyOD/htvwIAB1Zvc3SQvcUmWpSk/P98VFBTUdTGMSQtHHAErV+r7Ro10tO6ePcHEMQcP6oQtoM8BvvoqmFdg/vzoc/ia5CQi872ekuWymr4xacxv4gEN6M7BxIkwYgR8801Qm+/QQbN7zpsXHG8J3NKTJVwzJo35D3PDidn+8Ae9AXzwgQZ70ARva9fCXXcF59qQmfRkNX1j0tjxx8OgQaVz+3z1lS6ffTZozx8yRJcvvghNm+r7aEH/s89qrqymdljQNyaNjRsH//1vMELXzwckokHf76Pfs6f2Ojp4EM44Q9v1I4P+O+/AUUdpVlCTuiz5vuCdAAAS+0lEQVToG5MBhg7V2vzAgbp+6aVQVATveUMpmzcP8vcMGAAtW5YN+osW6dJ/MGxSkwV9YzLAVVdpQrdevXQA2O23a23/scd0f7Nm0MdLgJ6fr1MzhoP+gQN6kwDrz5/qLOgbk0HGjoW339YcPyeeCIsX6/ZmzeB739NmnuOPD4L+7t36wLdpU3jpJT3WRu6mNgv6xmSQli01qINOyu5r3lwTtC1erAG+dWt9FpCTA//+t+YC+vRTPdZq+qnNumwak6F++lOt2a9fH/TY8fnJbg8c0KAfZkE/tVlN35gMJQLf+U707JvhDOeRc+euWgU336wTqpvUY0HfGFPG5s2l1/0kcu3bw8KFmsPntdcS/72zZ+vnm5pjQd8YU8Z55+ly8GBd3nSTNvNceGFwzNq1if1O5zRJXeS8vyaxLOgbY8oYOlSD8MiRun7ssXDJJUFaBwiC/t69+lB49erqfeeyZdU738THgr4xJqbvf19vAP6grnA+/oIC6N4d/vpXePRRmDGjet/15pvVO9/Ex3rvGGNiOvJIeP31YD08jeOcOfrXgJ+j3x+xG4+NG3VsgJ/i+ZNPYPr0YP++fZrq2SSe1fSNMXEbNQouvlj79PtTcfjNPP4D2NWrg33ROKd5+u+6C5Yv195B3/0uzJ0bTOe4bl2NXULGs6BvjIlbTg5MmxakbAhbtgyeew66dIHf/Cb2Z2zdqkH900/15jFmDKxZo91AX3hBj1m+XJ8VmMSzoG+MqTQ/D78vN1czdI4cqRk6J04MRvBGWrVKl0VF+lfC88/r+uDBQTbQs86CCy6okaJnPAv6xphK84P+Kafo8ic/0WW7djrHbkkJPP201ugPHgzOmzIFZs3S9598osuSEl326qU3D9+sWVrjN4llQd8YU2lduujy6qu1985NN0Fxsb6GDIGOHeH99yEvT2v9xxwD990HV16pGT6h9M2gSRPo1Ekf7vqysuChh2rrijJHXEFfRIaLSKGIFInI2Cj7/ywiC73XchHZHtr3IxH5zHv9KJGFN8bUjQEDtP195EjN4dOokdb+s7J0f/fu8PLLOkvXPfdAYSHceafu++absp/Xo0fwENd33nnaFXTvXpgwAcaPD/atXWv9+quqwi6bIpIFTAKGAcXAPBGZ6Zxb6h/jnPtV6Phrgb7e+xzgNiAfcMB879xtCb0KY0ytEtFUzLF07w6vvqrvt3n/t8dKyXzEEcE4AIAPP9Sa/4YN2vf/iSf0xiECjRtrd8/Vq2HBgrLNP2vX6rOEoUOrfm3pLp5++gOAIufcSgARmQaMAJbGOH40GugBzgRec85t9c59DRgOPFGdQhtjklv37roU0S6a/jIrS5t12rXToN62rU6/mJ0dnOunfj7mGP2cm2+GLVt02x136LHt2sGKFTBpkgb/Rx7R/RMmwMMPw549+kDZlBXPf5YOwJrQerG3rQwR6Qx0BeZU9lxjTPrwg/7ZZ0OrVtoEBHDmmZq7//TTdb1jR23HDwd9nwjcemvp5G+7dun6p59qM9Gdd8I//xk8H1izRgd2+TcJU1Y8QV+ibIs19GIU8JRzzn9EE9e5IjJGRApEpGBT5MScxpiU07Mn1K+vk6yvW6c18txcHYS1cKE+1AUN+uUZNQr694eTTio9Qtfv8bN+Pezfrw+QIRgoVtHgrkmTtLeQPzF8JomneacYCP80uUCs/6SjgKsjzj0l4ty5kSc556YAUwDy8/PLGctnjEkFLVtql8xu3TT4g7bDiwQPbHv31vl4y1OvnnYBBRg+XG8YX31V9riiIujcOQj269YFE71Hmj0brrlG33/6KZxwQuWuLdXFE/TnAXki0hVYiwb2SyIPEpGjgcOA90KbXwHuEpHDvPUzgHHVKrExJiUcfXTp9cg29njz5vuzek2apHP2nn665gDynw8A3HCDjhZev17Xy6vpL1kSvE90euhUUGHQd86ViMg1aADPAqY655aIyHigwDk30zt0NDDNuSDrhnNuq4j8Dr1xAIz3H+oaYzJbZBfNivipH/LytGbfsyfMnw+HHFI22dtnn2lw79mz7Ofs3Bm8t6Afg3NuFjArYttvI9Zvj3HuVGBqFctnjDGlnHiiPgzu3l0f7GZlle2zf8898H//p907d+4sPdJ3xw59PnDwoD4LWLAgsyZusU5NxpiU8sADOgbg3ns1M+eRR5be7/8FsW8fXHqpdv3csyfYv2MHtGgBhx+uaSH69YudJygdWdA3xqSU7GwdAdysmc7Ze8EFcNllQW0+PNHLCy9owA8P4tq5U/9S6NABtnu5AyzoG2NMirjsMnjsMW3zFwm6YfopIUDb/t/zupjs2KE3jHCm0M8/r73y1jWbOcsYkxZ+8ANttmnXTpO8ffe7MNPrZnLDDdr+v2JF6Zq+b9Uq7REUbZBYurGavjEmLYwapaNz77lHk7SNGKF99zt31kDvHPznP9Fr+g8/rA93l3rJZb7+WrOB7t5dJ5dSoyzoG2PSSr16GsCvuEJr8L17B/tefFGDfvPmcOyxOnCsd+9g7l+/D/9bb2menxdfrPXi1zgL+saYtObnARo8WHv7bNyoQf+MMzTpmz8RDAQZQf20DoWFtVnS2mFt+saYtPbDH+qyTx94+21936yZPvTNyQmmaAQdybtypSZuA+3Vs2KFppOo7GCyZGU1fWNMWuvVS9v5w/35mzcP3vftG/T0eeopze//1FO6/tJLet6sUkNTE+e442p/YJgFfWNMRgjX6MPTMp58sjb59OkTtOn78/f63T/nzaNGfPxx/DmIEsWCvjEmI7RsGbwP1/T9fYcfHvtc/yZQU8LzBdc0C/rGmIwQbpOPDPpQNuj7ydrq14cPPtDJ34uKon+2czB6NLz+etXKtnYtHDhQtXMry4K+MSZj+BOxhJt3fJFB/5JL4MEH4Ve/0qA8YQJcdJFO2uL7+mtNIf3IIzBtWtW7eK5YoYPLamNuXwv6xpiMkZOjy/KCvl/D79wZrrpKZ+7yLVigSdp8hYWa12fGDF2vaMauWFas0LEB5TUxJYoFfWNMxjjnHF1GC/r+1I1XX603Bz/YDxqkyxkzdNL2yZO1OQeCEbwffqjLyubnb9xYly+9pA+Thwyp3PlVYf30jTEZ47774MorS+fX951xBvz735rO4ec/D7Z36KCTsIto/p4rrtBBXosXB5O3+L181q3Th7L16sXXr9+f6/eZZ3RZG0FfQhNdJYX8/HxXUFBQ18UwxpgyvvpKbxgtWkTPzNmggaZ7/uUv9VUe58pOIenfXKpCROY75yqYddiad4wxJm6NGsGPfxw7FfP+/ToBvD/yF+B3v9PBXeeco+99fm+dO+6A227TOYBrY9SvNe8YY0wlXHUV3H+/TtD+0kvQqhVs3lz6mKVLtaZ/2mka6M85R7tzbtsGH32ks3mNG6fHNmoEN95Ye+W3oG+MMZWQl6c1/TZttDtnp05w881w2GFBwrbCQs3bM3eu1ugLCjTd87Jlmq558+Ygs6ffjbS2WPOOMcZUUocOOmjrgQfg7LN12/HHB/v9R6X+g97Vq3W5ZYsG++LiIOjX9sQtcQV9ERkuIoUiUiQiY2Mcc5GILBWRJSLyeGj7QRFZ6L1mJqrgxhiTDPyunscfrzeC006r+Jy1a7XmD7Uf9Cts3hGRLGASMAwoBuaJyEzn3NLQMXnAOGCQc26biISmJmavc65PgsttjDFJoXlzeO45OPFEGD5cE7t17KhjAfyunJEOHAjSNydd0AcGAEXOuZUAIjINGAEsDR3zM2CSc24bgHPuy0QX1BhjktWIEbps21aXkyfrA94LL9Q2+3374NBDtUnnm2/0mBUrdJmMzTsdgDWh9WJvW9hRwFEi8o6IvC8iw0P7GopIgbf93GqW1xhjkt5VV8F552lt32/u6dJFUzz4aR785G3JWNOP1nM0ckTXIUAecAqQC7wtIr2cc9uBTs65dSLSDZgjIp8451aU+gKRMcAYgE6dOlXyEowxJvnUq6fdNA8/XJt8OneGv/9dR/UedVQQ9JOx904x0DG0ngtEphUqBp53zh1wzn0OFKI3AZxz67zlSmAuUGaeGOfcFOdcvnMuv3Xr1pW+CGOMSUbHH689fc44A049Fdq105m5GjRI7uadeUCeiHQVkQbAKCCyF85zwKkAItIKbe5ZKSKHiUh2aPsgSj8LMMaYtPfii5qPH/QvgNzcJA76zrkS4BrgFWAZMN05t0RExouIl7OOV4AtIrIUeAP4tXNuC9AdKBCRRd72P4R7/RhjTCZq3VoHaUFytunjnJsFzIrY9tvQewdc773Cx7wLHFv9YhpjTPpo0SJ4n3Q1fWOMMYkVnq7Rgr4xxqS5cE0/GXvvGGOMSSCr6RtjTAaxoG+MMRkk3LzToEHtfrcFfWOMqWXhmn7klIk1zYK+McbUsnDQr20W9I0xppaFm3dqmwV9Y4ypZVbTN8aYDGJB3xhjMog17xhjTAZp2rTuvtuCvjHG1LLa7qZZ6rvr7quNMcbUNgv6xhiTQeLKp2+MMSaxnnwSmjSp/e+1oG+MMXXgoovq5nuteccYYzKIBX1jjMkgFvSNMSaDWNA3xpgMYkHfGGMySFxBX0SGi0ihiBSJyNgYx1wkIktFZImIPB7a/iMR+cx7/ShRBTfGGFN5FXbZFJEsYBIwDCgG5onITOfc0tAxecA4YJBzbpuItPG25wC3AfmAA+Z7525L/KUYY4ypSDw1/QFAkXNupXNuPzANGBFxzM+ASX4wd8596W0/E3jNObfV2/caMDwxRTfGGFNZ8QzO6gCsCa0XAydEHHMUgIi8A2QBtzvnXo5xbofILxCRMcAYb3W3iBTGVfqyWgGbq3huskmXa0mX6wC7lmRl16I6x3NQPEFfomxzUT4nDzgFyAXeFpFecZ6Lc24KMCWOspRLRAqcc/nV/ZxkkC7Xki7XAXYtycqupXLiad4pBjqG1nOBdVGOed45d8A59zlQiN4E4jnXGGNMLYkn6M8D8kSkq4g0AEYBMyOOeQ44FUBEWqHNPSuBV4AzROQwETkMOMPbZowxpg5U2LzjnCsRkWvQYJ0FTHXOLRGR8UCBc24mQXBfChwEfu2c2wIgIr9DbxwA451zW2viQjzVbiJKIulyLelyHWDXkqzsWipBnCvTxG6MMSZN2YhcY4zJIGkR9OMZMZzMRGSViHwiIgtFpMDbliMir3kjmV/znokkHRGZKiJfisji0LaoZRd1n/c7fSwi/equ5GXFuJbbRWSt99ssFJGzQ/vGeddSKCJn1k2poxORjiLyhogs80bJX+dtT6nfppzrSLnfRUQaisiHIrLIu5Y7vO1dReQD7zd50nt2iohke+tF3v4uCSmIcy6lX+hzhhVAN6ABsAjoUdflquQ1rAJaRWz7IzDWez8WuKeuyxmj7EOAfsDiisoOnA28hHblPRH4oK7LH8e13A7cGOXYHt6/tWygq/dvMKuuryFUvvZAP+99U2C5V+aU+m3KuY6U+128/7ZNvPf1gQ+8/9bTgVHe9oeAn3vvfwE85L0fBTyZiHKkQ00/nhHDqWgE8Jj3/jHg3DosS0zOubeAyIfzsco+AviHU+8DLUSkfe2UtGIxriWWEcA059zXTrspF6H/FpOCc269c+4j7/0uYBk6MDKlfptyriOWpP1dvP+2u73V+t7LAacBT3nbI38T/7d6ChgqItHGPlVKOgT9uEb9JjkHvCoi873RyQBtnXPrQf/hA23qrHSVF6vsqfpbXeM1eUwNNbOlzLV4zQJ90Zplyv42EdcBKfi7iEiWiCwEvkTT0qwAtjvnSrxDwuX99lq8/TuAltUtQzoE/bhG/Sa5Qc65fsBZwNUiMqSuC1RDUvG3ehA4AugDrAfu9banxLWISBPgaeCXzrmd5R0aZVvSXE+U60jJ38U5d9A51wcdqDoA6B7tMG9ZI9eSDkE/5Uf9OufWecsvgWfRfwwb/T+vveWXsT8h6cQqe8r9Vs65jd7/qN8AfyVoKkj6axGR+mig/Ldz7hlvc8r9NtGuI5V/FwDn3HZgLtqm30JE/DFT4fJ+ey3e/ubE3/wYUzoE/XhGDCctEWksIk399+io5cXoNfjzD/wIeL5uSlglsco+E7jM6ylyIrDDb2pIVhHt2iPR3wb0WkZ5PSy6omlHPqzt8sXitf3+DVjmnPtTaFdK/TaxriMVfxcRaS0iLbz3hwKno88o3gAu8A6L/E383+oCYI7znupWS10/0U7EC+15sBxtH7ulrstTybJ3Q3sbLAKW+OVH2+5mA595y5y6LmuM8j+B/nl9AK2Z/CRW2dE/Vyd5v9MnQH5dlz+Oa/mnV9aPvf8J24eOv8W7lkLgrLouf8S1nIQ2BXwMLPReZ6fab1POdaTc7wL0BhZ4ZV4M/Nbb3g29MRUBM4Bsb3tDb73I298tEeWwEbnGGJNB0qF5xxhjTJws6BtjTAaxoG+MMRnEgr4xxmQQC/rGGJNBLOgbY0wGsaBvjDEZxIK+McZkkP8HQdeKDdUnrO0AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "#定义常量\n",
    "rnn_unit=15       #hidden layer units\n",
    "input_size=11\n",
    "output_size=1\n",
    "PATH = \"modelBATTERY\"\n",
    "lr=0.0006         #学习率\n",
    "#——————————————————导入数据——————————————————————\n",
    "f=open('dataset/B0005_1.csv')\n",
    "df=pd.read_csv(f)     #读入数据\n",
    "data=df.iloc[:,3:15].values  #取第4-14列\n",
    "\n",
    "\n",
    "#获取训练集\n",
    "def get_train_data(batch_size=60,time_step=20,train_begin=1,train_end=300):\n",
    "    batch_index=[]\n",
    "    data_train=data[train_begin:train_end]\n",
    "    normalized_train_data=(data_train-np.mean(data_train,axis=0))/np.std(data_train,axis=0)  #标准化\n",
    "    train_x,train_y=[],[]   #训练集 \n",
    "    for i in range(len(normalized_train_data)-time_step):\n",
    "       if i % batch_size==0:\n",
    "           batch_index.append(i)\n",
    "       x=normalized_train_data[i:i+time_step,:11]\n",
    "       y=normalized_train_data[i:i+time_step,11,np.newaxis]\n",
    "       train_x.append(x.tolist())\n",
    "       train_y.append(y.tolist())\n",
    "    batch_index.append((len(normalized_train_data)-time_step))\n",
    "    return batch_index,train_x,train_y\n",
    "\n",
    "\n",
    "\n",
    "#获取测试集\n",
    "def get_test_data(time_step=20,test_begin=1):\n",
    "    data_test=data[test_begin:]\n",
    "    mean=np.mean(data_test,axis=0)\n",
    "    std=np.std(data_test,axis=0)\n",
    "    normalized_test_data=(data_test-mean)/std  #标准化\n",
    "    size=(len(normalized_test_data)+time_step-1)//time_step  #有size个sample \n",
    "    test_x,test_y=[],[]  \n",
    "    for i in range(size-1):\n",
    "       x=normalized_test_data[i*time_step:(i+1)*time_step,:11]\n",
    "       y=normalized_test_data[i*time_step:(i+1)*time_step,11]\n",
    "       test_x.append(x.tolist())\n",
    "       test_y.extend(y)\n",
    "    test_x.append((normalized_test_data[(i+1)*time_step:,:11]).tolist())\n",
    "    test_y.extend((normalized_test_data[(i+1)*time_step:,11]).tolist())\n",
    "    return mean,std,test_x,test_y\n",
    "\n",
    "\n",
    "\n",
    "#——————————————————定义神经网络变量——————————————————\n",
    "#输入层、输出层权重、偏置\n",
    "\n",
    "weights={\n",
    "         'in':tf.Variable(tf.random_normal([input_size,rnn_unit])),\n",
    "         'out':tf.Variable(tf.random_normal([rnn_unit,1]))\n",
    "        }\n",
    "biases={\n",
    "        'in':tf.Variable(tf.constant(0.1,shape=[rnn_unit,])),\n",
    "        'out':tf.Variable(tf.constant(0.1,shape=[1,]))\n",
    "       }\n",
    "\n",
    "#——————————————————定义神经网络变量——————————————————\n",
    "def lstm(X):     \n",
    "    batch_size=tf.shape(X)[0]\n",
    "    time_step=tf.shape(X)[1]\n",
    "    w_in=weights['in']\n",
    "    b_in=biases['in']  \n",
    "    input=tf.reshape(X,[-1,input_size])  #需要将tensor转成2维进行计算，计算后的结果作为隐藏层的输入\n",
    "    input_rnn=tf.matmul(input,w_in)+b_in\n",
    "    input_rnn=tf.reshape(input_rnn,[-1,time_step,rnn_unit])  #将tensor转成3维，作为lstm cell的输入\n",
    "    cell=tf.nn.rnn_cell.BasicLSTMCell(rnn_unit)\n",
    "    init_state=cell.zero_state(batch_size,dtype=tf.float32)\n",
    "    output_rnn,final_states=tf.nn.dynamic_rnn(cell, input_rnn,initial_state=init_state, dtype=tf.float32)  #output_rnn是记录lstm每个输出节点的结果，final_states是最后一个cell的结果\n",
    "    output=tf.reshape(output_rnn,[-1,rnn_unit]) #作为输出层的输入\n",
    "    w_out=weights['out']\n",
    "    b_out=biases['out']\n",
    "    pred=tf.matmul(output,w_out)+b_out\n",
    "    return pred,final_states\n",
    "\n",
    "\n",
    "\n",
    "#——————————————————训练模型——————————————————\n",
    "def train_lstm(batch_size=80,time_step=15,train_begin=1,train_end=300):\n",
    "    X=tf.placeholder(tf.float32, shape=[None,time_step,input_size])\n",
    "    Y=tf.placeholder(tf.float32, shape=[None,time_step,output_size])\n",
    "    batch_index,train_x,train_y=get_train_data(batch_size,time_step,train_begin,train_end)\n",
    "    pred,_=lstm(X)\n",
    "    #损失函数\n",
    "    loss=tf.reduce_mean(tf.square(tf.reshape(pred,[-1])-tf.reshape(Y, [-1])))\n",
    "    train_op=tf.train.AdamOptimizer(lr).minimize(loss)\n",
    "    saver=tf.train.Saver(tf.global_variables(),max_to_keep=15)\n",
    "    # module_file = tf.train.latest_checkpoint()\n",
    "    with tf.Session() as sess:\n",
    "        sess.run(tf.global_variables_initializer())\n",
    "        ckpt = tf.train.get_checkpoint_state(PATH)\n",
    "        if ckpt and ckpt.model_checkpoint_path:\n",
    "            saver.restore(sess, ckpt.model_checkpoint_path)\n",
    "            print(\"Load!\")\n",
    "        else:\n",
    "            tf.global_variables_initializer().run()\n",
    "        # saver.restore(sess, module_file)\n",
    "        #重复训练10000次\n",
    "        for i in range(1001):\n",
    "            for step in range(len(batch_index)-1):\n",
    "                _,loss_=sess.run([train_op,loss],feed_dict={X:train_x[batch_index[step]:batch_index[step+1]],Y:train_y[batch_index[step]:batch_index[step+1]]})\n",
    "            print(i,loss_)\n",
    "            if i % 200==0:\n",
    "                saver.save(sess, 'modelBATTERY/model.ckpt', global_step=i)\n",
    "                print(\"保存模型：\")\n",
    "\n",
    "\n",
    "\n",
    "#————————————————预测模型————————————————————\n",
    "def prediction(time_step=20):\n",
    "    X=tf.placeholder(tf.float32, shape=[None,time_step,input_size])\n",
    "    #Y=tf.placeholder(tf.float32, shape=[None,time_step,output_size])\n",
    "    mean,std,test_x,test_y=get_test_data(time_step)\n",
    "    pred,_=lstm(X)     \n",
    "    saver=tf.train.Saver(tf.global_variables())\n",
    "    with tf.Session() as sess:\n",
    "        #参数恢复\n",
    "        ckpt = tf.train.get_checkpoint_state(PATH)\n",
    "        if ckpt and ckpt.model_checkpoint_path:\n",
    "            saver.restore(sess, ckpt.model_checkpoint_path)\n",
    "            print(\"Load!\")\n",
    "        else:\n",
    "            tf.global_variables_initializer().run()\n",
    "        # module_file = tf.train.latest_checkpoint()\n",
    "        # saver.restore(sess, module_file)\n",
    "        test_predict=[]\n",
    "        for step in range(len(test_x)-1):\n",
    "            prob=sess.run(pred,feed_dict={X:[test_x[step]]})   \n",
    "            predict=prob.reshape((-1))\n",
    "            test_predict.extend(predict)\n",
    "        test_y=np.array(test_y)*std[11]+mean[11]\n",
    "        test_predict=np.array(test_predict)*std[11]+mean[11]\n",
    "        test_predict1 = test_predict[:300]\n",
    "        test_predict2 = test_predict[301:]\n",
    "        acc=np.average(np.abs(test_predict-test_y[:len(test_predict)])/test_y[:len(test_predict)])  #偏差\n",
    "        \n",
    "        x = range(1,400)\n",
    "        #以折线图表示结果\n",
    "        plt.figure()\n",
    "#         prediction=plt.plot(list(range(len(test_predict1))), test_predict1, color='b',label='predict')\n",
    "        prediction=plt.plot(x[:300], test_predict1, color='b',label='predict')\n",
    "        prediction=plt.plot(x[301:301+len(test_predict2)], test_predict2, color='g',label='predict1')\n",
    "        test=plt.plot(list(range(len(test_y))), test_y,  color='r',label='real_soh')\n",
    "        plt.show()\n",
    "        \n",
    "\n",
    "\n",
    "# train_lstm()\n",
    "\n",
    "prediction() "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
